package org.mybatis.generator.api.plus;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author wangfupeng
 */
public class MybatisPluginService extends PluginAdapter {

    private FullyQualifiedJavaType slf4jLogger;
    private FullyQualifiedJavaType slf4jLoggerFactory;
    private FullyQualifiedJavaType autowired;
    private FullyQualifiedJavaType service;
    private FullyQualifiedJavaType lazy;
    private FullyQualifiedJavaType string;
    private FullyQualifiedJavaType integer;
    private FullyQualifiedJavaType longT;
    private FullyQualifiedJavaType listT;

    private FullyQualifiedJavaType serviceType;
    private FullyQualifiedJavaType mapperType;
    private FullyQualifiedJavaType modelType;
    private FullyQualifiedJavaType modelExampleType;
    private FullyQualifiedJavaType javaUtilListType;
    private FullyQualifiedJavaType cacheFetchLater;
    private FullyQualifiedJavaType cacheMockFetchLater;
    private FullyQualifiedJavaType lockWithCache;
    private FullyQualifiedJavaType mockExecuteLater;
    private FullyQualifiedJavaType cacheServiceType;
    private FullyQualifiedJavaType cacheEmptyInstanceType;

    private String basePackage;
    private String servicePackage;
    private String project;
    private String modelUrl;
    private String aspectPackage;
    private String createFeign;
    private String createDistinct;
    private String createBatch;
    private String mapperPackage;
    private String modelPackage;
    private String eurekaServiceName;
    private String feignClientUrl;
    private String responseType;
    private String deleteStatus;
    private String createCustomService;
    private String createAuthUser;

    private FullyQualifiedJavaType stringType;
    private FullyQualifiedJavaType integerType;
    private FullyQualifiedJavaType booleanType;
    private FullyQualifiedJavaType byteType;
    private FullyQualifiedJavaType doubleType;
    private FullyQualifiedJavaType floatType;
    private FullyQualifiedJavaType longType;
    private FullyQualifiedJavaType shortType;
    private FullyQualifiedJavaType bigDecimalType;
    private FullyQualifiedJavaType dateType;

    /**
     * 所有的方法
     */
    private List<Method> methods;

    /**
     * 是否添加注解
     */
    public MybatisPluginService() {
        super();
        // default is slf4j
        slf4jLogger = new FullyQualifiedJavaType("org.slf4j.Logger");
        slf4jLoggerFactory = new FullyQualifiedJavaType("org.slf4j.LoggerFactory");
        autowired = new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired");
        service = new FullyQualifiedJavaType("org.springframework.stereotype.Service");
        lazy = new FullyQualifiedJavaType("org.springframework.context.annotation.Lazy");
        autowired = new FullyQualifiedJavaType("org.springframework.beans.factory.annotation.Autowired");
        listT = new FullyQualifiedJavaType("java.util.List");
        string = new FullyQualifiedJavaType("java.lang.String");
        integer = new FullyQualifiedJavaType("java.lang.Integer");
        longT = new FullyQualifiedJavaType("java.lang.Long");
        methods = new ArrayList<Method>();
    }

    /**
     * 读取配置文件
     */
    @Override
    public boolean validate(List<String> warnings) {
        this.modelUrl = context.getJavaModelGeneratorConfiguration().getTargetPackage();
        this.basePackage = properties.getProperty("basePackage");
        this.servicePackage = properties.getProperty("servicePackage");
        this.project = properties.getProperty("targetProject");
        this.aspectPackage = properties.getProperty("aspectPackage");
        this.createFeign = properties.getProperty("createFeign");
        this.createDistinct = properties.getProperty("createDistinct");
        this.createBatch = properties.getProperty("createBatch");
        this.mapperPackage = properties.getProperty("mapperPackage");
        this.modelPackage = properties.getProperty("modelPackage");
        this.eurekaServiceName = properties.getProperty("eurekaServiceName");
        this.feignClientUrl = properties.getProperty("feignClientUrl");
        this.responseType = properties.getProperty("responseType");
        this.deleteStatus = properties.getProperty("deleteStatus");
        this.createAuthUser = properties.getProperty("createAuthUser");
        this.createCustomService = properties.getProperty("createCustomService");
        this.cacheFetchLater = new FullyQualifiedJavaType("com.gitee.fufu669.aspect.CacheFetchLater");
        this.cacheMockFetchLater = new FullyQualifiedJavaType("com.gitee.fufu669.aspect.CacheMockFetchLater");
        this.lockWithCache = new FullyQualifiedJavaType("com.gitee.fufu669.aspect.LockWithCache");
        this.mockExecuteLater = new FullyQualifiedJavaType("com.gitee.fufu669.aspect.MockExecuteLater");

        this.createFeign = this.createFeign == null ? "false" : this.createFeign;
        this.createDistinct = this.createDistinct == null ? "false" : this.createDistinct;
        this.createBatch = this.createBatch == null ? "false" : this.createBatch;
        this.deleteStatus = this.deleteStatus == null ? "2" : this.deleteStatus;
        this.createAuthUser = this.createAuthUser == null ? "false" : this.createAuthUser;
        this.createCustomService = this.createCustomService == null ? "false" : this.createCustomService;
        return true;
    }

    @Override
    public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
        List<GeneratedJavaFile> files = new ArrayList<GeneratedJavaFile>();
        String table = introspectedTable.getBaseRecordType();// 取Service名称【com.coolead.service.PetService】
        System.out.println("========" + table+"=========");
        try {
            String tableName = table.replaceAll(this.modelUrl + ".", "");
            if(introspectedTable.getMyBatis3JavaMapperType()!=null) {
                mapperType = new FullyQualifiedJavaType(introspectedTable.getMyBatis3JavaMapperType());
            }
            modelType = new FullyQualifiedJavaType(modelUrl + "." + tableName);
            modelExampleType = new FullyQualifiedJavaType(modelUrl + "." + tableName + "Example");
            javaUtilListType = new FullyQualifiedJavaType("java.util.List");

            stringType = new FullyQualifiedJavaType("java.lang.String");
            integerType = new FullyQualifiedJavaType("java.lang.Integer");
            booleanType = new FullyQualifiedJavaType("java.lang.Boolean");
            byteType = new FullyQualifiedJavaType("java.lang.Byte");
            doubleType = new FullyQualifiedJavaType("java.lang.Double");
            floatType = new FullyQualifiedJavaType("java.lang.Float");
            longType = new FullyQualifiedJavaType("java.lang.Long");
            shortType = new FullyQualifiedJavaType("java.lang.Short");
            bigDecimalType = new FullyQualifiedJavaType("java.lang.BigDecimal");
            dateType = new FullyQualifiedJavaType("java.util.Date");
            serviceType = new FullyQualifiedJavaType(servicePackage + "." + tableName + "Service");
            cacheServiceType = new FullyQualifiedJavaType("com.gitee.fufu669.service.CacheService");
            cacheEmptyInstanceType = new FullyQualifiedJavaType("com.gitee.fufu669.config.exception.CacheEmptyInstance");

            String[] servicePackages = servicePackage.split("\\.");
            String servicePackageCustom = "";
            for (int i = 0; i < servicePackages.length - 1; i++) {
                servicePackageCustom += servicePackages[i] + ".";
            }
            TopLevelClass topLevelClass = new TopLevelClass(serviceType);
            // 导入必须的类
            addImport(topLevelClass);
            addLogger(topLevelClass);
            addDeleteStatus(topLevelClass);
            addService(topLevelClass, introspectedTable, tableName, files);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("========" + table+"出错了=========\n");
        }
        return files;
    }

    private void addDeleteStatus(TopLevelClass topLevelClass) {
        Field field = new Field();
        field.setFinal(true);
        field.setInitializationString(deleteStatus);
        field.setName("STATUS_DELETE");
        field.setStatic(true);
        field.setFinal(true);
        field.setType(new FullyQualifiedJavaType("Integer"));
        field.setVisibility(JavaVisibility.PUBLIC);
        topLevelClass.addField(field);
    }

    /**
     * import must class 导入必要的class
     */
    private void addImport(TopLevelClass topLevelClass) {
        // addImportedType是往一个set里面加数据，所以可以重复添加。
        topLevelClass.addImportedType(mapperType);
        topLevelClass.addImportedType(modelType);
        topLevelClass.addImportedType(modelExampleType);
        topLevelClass.addImportedType(javaUtilListType);
        topLevelClass.addImportedType(slf4jLogger);
        topLevelClass.addImportedType(slf4jLoggerFactory);
        topLevelClass.addImportedType(service);
        topLevelClass.addImportedType(autowired);
        topLevelClass.addImportedType(string);
        topLevelClass.addImportedType(cacheFetchLater);
        topLevelClass.addImportedType(cacheMockFetchLater);
        topLevelClass.addImportedType(lockWithCache);
        topLevelClass.addImportedType(mockExecuteLater);
        topLevelClass.addImportedType(cacheEmptyInstanceType);
        topLevelClass.addImportedType(mapperType);
        topLevelClass.addImportedType(cacheServiceType);
    }

    /**
     * import logger
     */
    private void addLogger(TopLevelClass topLevelClass) {
        Field field = new Field();
        field.setFinal(true);
        field.setInitializationString("LoggerFactory.getLogger(" + topLevelClass.getType().getShortName() + ".class)"); // set
        // value
        field.setName("logger");
        field.setStatic(true);
        field.setType(new FullyQualifiedJavaType("Logger")); // type
        field.setVisibility(JavaVisibility.PUBLIC);
        topLevelClass.addField(field);
    }

    /**
     * add implements class
     *
     * @param introspectedTable
     * @param tableName
     * @param files
     */
    protected void addService(TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String tableName,
                              List<GeneratedJavaFile> files) {
        topLevelClass.setVisibility(JavaVisibility.PUBLIC);
        // set service
        topLevelClass.addJavaDocLine("/*" + introspectedTable.getRemarks() + "服务*/");
        topLevelClass.addAnnotation("@SuppressWarnings(\"rawtypes\")");
        topLevelClass.addAnnotation("@Lazy");
        topLevelClass.addImportedType(lazy);
        topLevelClass.addAnnotation("@Service");
        topLevelClass.addImportedType(service);
        // add import mapper
        addFieldMapper(topLevelClass, tableName, introspectedTable);
        addFieldCacheService(topLevelClass, tableName, introspectedTable);
        // add method
        topLevelClass.addMethod(createModelMethod(introspectedTable, tableName));
        topLevelClass.addMethod(createThenSetCacheFetchLaterAndCacheMockFetchLaterMethod(introspectedTable, tableName));
        topLevelClass.addMethod(createMockExecuteLaterThenSetCacheFetchLaterAndCacheMockFetchLaterMethod(introspectedTable, tableName));
        topLevelClass.addMethod(createModelMethodLockWithCache(introspectedTable, tableName));
        topLevelClass.addMethod(createModelMethodMockExecuteLater(introspectedTable, tableName));
        String pathForPrimaryKeyColumns = MybatisUtilCommon.getPathForPrimaryKeyColumns(introspectedTable);
        if (!"".equals(pathForPrimaryKeyColumns)) {
            topLevelClass.addMethod(deleteByExampleMethod(introspectedTable, tableName));
            topLevelClass.addMethod(deleteByExampleMethodMockExecuteLater(introspectedTable, tableName));
            topLevelClass.addMethod(deleteThenRemoveCacheFetchLaterAndCacheMockFetchLaterByPrimaryKeyMethod(introspectedTable, tableName));
            topLevelClass.addMethod(deleteByPrimaryKeyMethod(introspectedTable, tableName));
            topLevelClass.addMethod(deleteByPrimaryKeyMethodLockWithCache(introspectedTable, tableName));
            topLevelClass.addMethod(deleteByPrimaryKeyMethodMockExecuteLater(introspectedTable, tableName));
            topLevelClass.addMethod(deleteSetStatusByExampleMethod(introspectedTable, tableName));
            topLevelClass.addMethod(deleteSetStatusByExampleMethodMockExecuteLater(introspectedTable, tableName));
            topLevelClass.addMethod(deleteSetStatusByPrimaryKeyMethod(introspectedTable, tableName));
            topLevelClass.addMethod(deleteSetStatusAndSetCacheFetchLaterAndCacheMockFetchLaterByPrimaryKeyMethod(introspectedTable, tableName));
            topLevelClass.addMethod(deleteSetStatusByPrimaryKeyMethodLockWithCache(introspectedTable, tableName));
            topLevelClass.addMethod(deleteSetStatusByPrimaryKeyMethodMockExecuteLater(introspectedTable, tableName));
            if (MybatisUtilCommon.getExistNonePrimaryKeyColumns(introspectedTable)) {
                topLevelClass.addMethod(updateMethod(introspectedTable, tableName));
                topLevelClass.addMethod(updateThenSetCacheFetchLaterAndCacheMockFetchLaterMethod(introspectedTable, tableName));
                topLevelClass.addMethod(updateMethodLockWithCache(introspectedTable, tableName));
                topLevelClass.addMethod(updateMethodMockExecuteLater(introspectedTable, tableName));
                topLevelClass.addMethod(selectByPrimaryKeyWithoutCacheMethod(introspectedTable, tableName));
                topLevelClass.addMethod(selectByPrimaryKeyWithCacheFetchLaterMethod(introspectedTable, tableName));
                topLevelClass.addMethod(selectByPrimaryKeyWithoutCacheThenSetCacheFetchLaterAndCacheMockFetchLaterMethod(introspectedTable, tableName));
                topLevelClass.addMethod(selectByPrimaryKeyWithOnlyCacheIfNullThenGetDataSetCacheMethod(introspectedTable, tableName));
                topLevelClass.addMethod(selectByPrimaryKeyWithOnlyCacheMethod(introspectedTable, tableName));
                topLevelClass.addMethod(selectByPrimaryKeyCacheMockFetchLater(introspectedTable, tableName));
            }
        }
        topLevelClass.addMethod(updateByExampleMethod(introspectedTable, tableName));
        topLevelClass.addMethod(updateByExampleMethodLockWithCache(introspectedTable, tableName));
        topLevelClass.addMethod(updateByExampleMethodMockExecuteLater(introspectedTable, tableName));
        topLevelClass.addMethod(updateByExampleSelectiveMethod(introspectedTable, tableName));
        topLevelClass.addMethod(updateByExampleSelectiveMethodLockWithCache(introspectedTable, tableName));
        topLevelClass.addMethod(updateByExampleSelectiveMethodMockExecuteLater(introspectedTable, tableName));
        topLevelClass.addMethod(list(introspectedTable, tableName));
        topLevelClass.addMethod(listWithoutCache(introspectedTable, tableName));
        topLevelClass.addMethod(listCacheMockFetchLater(introspectedTable, tableName));
        topLevelClass.addMethod(countByExample(introspectedTable, tableName));
        topLevelClass.addMethod(countByExampleWithoutCache(introspectedTable, tableName));
        topLevelClass.addMethod(countByExampleCacheMockFetchLater(introspectedTable, tableName));
        GeneratedJavaFile file = new GeneratedJavaFile(topLevelClass, project, context.getJavaFormatter());
        files.add(file);
        if (createAuthUser.equals("true")) {
            MybatisUtilAuthUser.writeAuthUser(basePackage, project);
            MybatisUtilAuthUser.writeAuthUserAop(basePackage, project);
        }
        MybatisUtilException.writeCurrentServerErrorCode(basePackage, project);
        MybatisUtilException.writeErrorMessage(basePackage, project);
        MybatisUtilException.writeCurrentServerException(basePackage, project);
        MybatisUtilException.writeCurrentServerExceptionHandler(basePackage, project);
        if (!"false".equals(this.createDistinct)) {
            MybatisUtilDistinctMapper.writeDistinctMapper(basePackage, aspectPackage, project, topLevelClass, introspectedTable, tableName,mapperPackage);
            MybatisUtilDistinctService.writeDistinctService(basePackage, aspectPackage, project, topLevelClass, introspectedTable, tableName, servicePackage,mapperPackage, modelPackage);
        }
        if (!"false".equals(this.createFeign)) {
            MybatisUtilFeignClient.writeFeignClient(eurekaServiceName, feignClientUrl, basePackage, aspectPackage, project, topLevelClass, introspectedTable, tableName, servicePackage);
            MybatisUtilFeignWrapper.writeFeignWrapper(basePackage, aspectPackage, project, topLevelClass, introspectedTable, tableName, servicePackage);
        }
        if (!"false".equals(this.createBatch)) {
            MybatisUtilBatchMapper.writeBatchMapper(basePackage, aspectPackage, project, topLevelClass, introspectedTable, tableName,mapperPackage, modelPackage);
            MybatisUtilBatchService.writeBatchService(basePackage, aspectPackage, project, topLevelClass, introspectedTable, tableName, servicePackage,mapperPackage, modelPackage);
        }
        MybatisUtilCommon.writeTableNamesAndColumns(introspectedTable);
    }

    protected void addFieldMapper(TopLevelClass topLevelClass, String tableName, IntrospectedTable introspectedTable) {
        Field field = new Field();
        field.setName(getMapperShort());
        field.setType(mapperType);
        field.setVisibility(JavaVisibility.PRIVATE);
        field.addAnnotation("@Autowired");
        topLevelClass.addField(field);
    }

    protected void addFieldCacheService(TopLevelClass topLevelClass, String tableName, IntrospectedTable introspectedTable) {
        Field field = new Field();
        field.setName("cacheService");
        field.setType(cacheServiceType);
        field.setVisibility(JavaVisibility.PRIVATE);
        field.addAnnotation("@Autowired");
        topLevelClass.addField(field);
    }

    protected Method createThenSetCacheFetchLaterAndCacheMockFetchLaterMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*创建" + introspectedTable.getRemarks() + "，并设置缓存*/");
        method.setName("createThenSetCacheFetchLaterAndCacheMockFetchLater");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");
        method.addBodyLine("//往数据库里插入数据");
        method.addBodyLine("Integer result = " + getMapperShortWithDot() + "insert(" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
        method.addBodyLine("//获取参数");
        method.addBodyLine("Object[] argumentsValues = {" +
                MybatisUtilCommon.getParameterWithModelPointValueForPrimaryKeyColumns(introspectedTable,
                        MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())
                )
                + "};");
        method.addBodyLine("//设置缓存");
        method.addBodyLine("cacheService.setClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "" + "\"getWithCacheFetchLater\", argumentsValues, " +
                "" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
        method.addBodyLine("//设置另一个缓存");
        method.addBodyLine("cacheService.setClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "" + "\"getCacheMockFetchLater\", argumentsValues, " +
                "" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }


    protected Method createMockExecuteLaterThenSetCacheFetchLaterAndCacheMockFetchLaterMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*起多线程创建" + introspectedTable.getRemarks() + "，并设置缓存*/");
        method.addAnnotation("@MockExecuteLater");
        method.setName("createMockExecuteLaterThenSetCacheFetchLaterAndCacheMockFetchLater");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");
        method.addBodyLine("//往数据库里插入数据");
        method.addBodyLine("Integer result = " + getMapperShortWithDot() + "insert(" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
        method.addBodyLine("//获取参数");
        method.addBodyLine("Object[] argumentsValues = {" +
                MybatisUtilCommon.getParameterWithModelPointValueForPrimaryKeyColumns(introspectedTable,
                        MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())
                )
                + "};");
        method.addBodyLine("//设置缓存");
        method.addBodyLine("cacheService.setClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "" + "\"getWithCacheFetchLater\", argumentsValues, " +
                "" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
        method.addBodyLine("//设置另一个缓存");
        method.addBodyLine("cacheService.setClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "" + "\"getCacheMockFetchLater\", argumentsValues, " +
                "" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }


    protected Method createModelMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*创建" + introspectedTable.getRemarks() + "*/");
        method.setName("create");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");
        method.addBodyLine("//往数据库里插入数据");
        method.addBodyLine("Integer result = " + getMapperShortWithDot() + "insert(" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    protected Method createModelMethodLockWithCache(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*加一把分布式锁,然后创建" + introspectedTable.getRemarks() + "*/");
        method.addAnnotation("@LockWithCache");
        method.setName("createLockWithCache");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addBodyLine("//把所有字段设成非空");

        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");
        method.addBodyLine("//往数据库里插入数据");
        method.addBodyLine("Integer result = " + getMapperShortWithDot() + "insert" + "(" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    protected Method createModelMethodMockExecuteLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*用多线程创建" + introspectedTable.getRemarks() + "*/");
        method.addAnnotation("@MockExecuteLater");
        method.setName("createMockExecuteLater");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");
        method.addBodyLine("//往数据库里插入数据");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "insert" + "(" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private String getMapperShort() {
        return MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName());
    }

    private String getMapperShortWithDot() {
        return MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".";
    }

    protected Method selectByPrimaryKeyWithOnlyCacheMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*数据库中获取" + introspectedTable.getRemarks() + "的数据，并存入缓存*/");
        method.setName("getWithOnlyCache");
        method.setReturnType(modelType);
        List<IntrospectedColumn> introspectedColumns;
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addBodyLine("//获取参数");
        method.addBodyLine("Object[] argumentsValues = {" + MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) + "};");
        method.addBodyLine("//从缓存里拿数据");
        method.addBodyLine(modelType.getShortName() + " " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = " +
                "(" +
                "" + modelType.getShortName() +
                ")" +
                "cacheService.getClassMethodValue(\"" +
                servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "\"getWithCacheFetchLater\", argumentsValues" +
                ");");

        method.addBodyLine("//如果缓存非空");
        method.addBodyLine("if(null != " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ") {");
        method.addBodyLine("//则立即返回结果");
        method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ";");
        method.addBodyLine("}");
        method.addBodyLine("//继续查找另一个缓存数据");

        method.addBodyLine(/*modelType.getShortName() + " " +*/ MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = " +
                "(" +
                "" + modelType.getShortName() +
                ")" +
                "cacheService.getClassMethodValue(\"" +
                servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "\"getCacheMockFetchLater\", argumentsValues" +
                ");");

        method.addBodyLine("//如果缓存非空");
        method.addBodyLine("if(null != " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ") {");
        method.addBodyLine("//则设置前面为空的缓存，再返回结果");

        method.addBodyLine("cacheService.setClassMethodValue(\"" +
                servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "\"getWithCacheFetchLater\", argumentsValues, " +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                ");");

        method.addBodyLine("//再返回结果");
        method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ";");
        method.addBodyLine("}");
        method.addBodyLine("//否则就返回空");
        method.addBodyLine("return null;");
        return method;
    }

    protected Method selectByPrimaryKeyWithOnlyCacheIfNullThenGetDataSetCacheMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*数据库中获取" + introspectedTable.getRemarks() + "的数据，并存入缓存*/");
        method.setName("getCacheOnlyIfNullThenGetDataSetCache");
        method.setReturnType(modelType);
        List<IntrospectedColumn> introspectedColumns;
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addBodyLine("//获取参数");
        method.addBodyLine("Object[] argumentsValues = {" + MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) + "};");
        method.addBodyLine("//从缓存里拿数据");
        method.addBodyLine("Object object = " +
                "cacheService.getClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", "
                + "\"getWithCacheFetchLater\", argumentsValues" + ");");
        method.addBodyLine("//声明一个空实例。");
        method.addBodyLine(modelType.getShortName() + " " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = null;");
        method.addBodyLine("//如果数据非空。");
        method.addBodyLine("if(null != object ){");
        method.addBodyLine("//如果数据是特定的空实例");
        method.addBodyLine("if(\"com.gitee.fufu669.config.exception.CacheEmptyInstance\".equals(object.getClass().getName())){");
        method.addBodyLine("//则返回空。");
        method.addBodyLine("return getWithoutCacheThenSetCacheFetchLaterAndCacheMockFetchLater(" + MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) + ");");
        method.addBodyLine("}");
        method.addBodyLine("//如果非空，则把数据转成要用的实例。");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = (" +
                "" + modelType.getShortName() +
                ") object;");
        method.addBodyLine("//返回结果。");
        method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ";");
        method.addBodyLine("}");
        method.addBodyLine("//否则继续查找另一个缓存数据。");
        method.addBodyLine("object = " +
                "cacheService.getClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", "
                + "\"getCacheMockFetchLater\", argumentsValues" + ");");
        method.addBodyLine("//如果数据非空。");
        method.addBodyLine("if(null != object ){");
        method.addBodyLine("//如果数据是特定的空实例");
        method.addBodyLine("if(\"com.gitee.fufu669.config.exception.CacheEmptyInstance\".equals(object.getClass().getName())){");
        method.addBodyLine("//则返回空");
        method.addBodyLine("return getWithoutCacheThenSetCacheFetchLaterAndCacheMockFetchLater(" + MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) + ");");
        method.addBodyLine("}");
        method.addBodyLine("//如果非空，则把数据转成要用的实例。");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = (" +
                "" + modelType.getShortName() +
                ") object;");
        method.addBodyLine("//然后给前面为空的缓存塞入值");
        method.addBodyLine("cacheService.setClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "" + "\"getWithCacheFetchLater\", argumentsValues, " +
                "" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
        method.addBodyLine("//再返回结果");
        method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ";");
        method.addBodyLine("}");
        method.addBodyLine("//否则就获取数据库数据，设置缓存，再返回结果");
        method.addBodyLine("return getWithoutCacheThenSetCacheFetchLaterAndCacheMockFetchLater(" + MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) + ");");
        return method;
    }

    protected Method selectByPrimaryKeyWithoutCacheThenSetCacheFetchLaterAndCacheMockFetchLaterMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*数据库中获取" + introspectedTable.getRemarks() + "的数据，并存入缓存*/");
        method.setName("getWithoutCacheThenSetCacheFetchLaterAndCacheMockFetchLater");
        method.setReturnType(modelType);
        List<IntrospectedColumn> introspectedColumns;
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addBodyLine("//从数据库里查数据");
        method.addBodyLine(modelType.getShortName() + " " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = " +
                "getWithoutCache(" + MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) + ");");
        method.addBodyLine("//如果数据是空");
        method.addBodyLine("if(null == " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ") {");
        method.addBodyLine("//获取参数");
        method.addBodyLine("Object[] argumentsValues = {" + MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) + "};");
        method.addBodyLine("//把特定的空实例存入缓存");
        method.addBodyLine("cacheService.setClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "" + "\"getWithCacheFetchLater\", argumentsValues, new CacheEmptyInstance());");
        method.addBodyLine("//把特定的空实例存入另一个缓存");
        method.addBodyLine("cacheService.setClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "" + "\"getCacheMockFetchLater\", argumentsValues, new CacheEmptyInstance());");
        method.addBodyLine("//返回空");
        method.addBodyLine("return null;");
        method.addBodyLine("}");
        method.addBodyLine("//获取参数");
        method.addBodyLine("Object[] argumentsValues = {" + MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) + "};");
        method.addBodyLine("//把数据存入缓存");
        method.addBodyLine("cacheService.setClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "" + "\"getWithCacheFetchLater\", argumentsValues, " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
        method.addBodyLine("//把数据存入另一个缓存");
        method.addBodyLine("cacheService.setClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "" + "\"getCacheMockFetchLater\", argumentsValues, " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
        method.addBodyLine("//返回结果");
        method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ";");
        return method;
    }

    protected Method selectByPrimaryKeyWithCacheFetchLaterMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*自动缓存获取" + introspectedTable.getRemarks() + "的数据*/");
        method.setName("getWithCacheFetchLater");
        method.setReturnType(modelType);
        List<IntrospectedColumn> introspectedColumns;
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//返回结果");
        method.addBodyLine("return "
                + getMapperShortWithDot() +
                "selectByPrimaryKey" + "(" +
                MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) +
                ");");

        method.addAnnotation("@CacheFetchLater");
        return method;
    }

    protected Method selectByPrimaryKeyWithoutCacheMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*无缓存获取" + introspectedTable.getRemarks() + "的数据*/");
        method.setName("getWithoutCache");
        method.setReturnType(modelType);
        List<IntrospectedColumn> introspectedColumns;
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//返回结果");
        method.addBodyLine("return " +
                getMapperShortWithDot() +
                "selectByPrimaryKey" +
                "(" +
                MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) +
                ");");

        return method;
    }

    protected Method selectByPrimaryKeyCacheMockFetchLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*纯缓存获取" + introspectedTable.getRemarks() + "的数据*/");
        method.setName("getCacheMockFetchLater");
        method.setReturnType(modelType);
        List<IntrospectedColumn> introspectedColumns;
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//返回结果");
        method.addBodyLine("return " +
                getMapperShortWithDot() +
                "selectByPrimaryKey" +
                "(" +
                MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) +
                ");");

        method.addAnnotation("@CacheMockFetchLater");
        return method;
    }

    private Method updateThenSetCacheFetchLaterAndCacheMockFetchLaterMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*按关键字更改" + introspectedTable.getRemarks() + "实例，并置入缓存中，要求传入实例是完整实例。*/");
        method.setName("updateThenSetCacheFetchLaterAndCacheMockFetchLater");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");

        method.addBodyLine("//按关键字更改");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "updateByPrimaryKeySelective" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                ");");

        method.addBodyLine("//同时设置2个缓存");
        method.addBodyLine("//获取参数");
        method.addBodyLine("Object[] argumentsValues = {" +
                MybatisUtilCommon.getParameterWithModelPointValueForPrimaryKeyColumns(introspectedTable,
                        MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())
                )
                + "};");

        method.addBodyLine("//设置缓存");
        method.addBodyLine("cacheService.setClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " + "\"getWithCacheFetchLater\", argumentsValues, " +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                ");");


        method.addBodyLine("//设置另一个缓存");
        method.addBodyLine("cacheService.setClassMethodValue(\"" +
                servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                "\"getCacheMockFetchLater\", argumentsValues, " +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method updateMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*按关键字更改" + introspectedTable.getRemarks() + "实例，要传入基础关键字，其余如果是null就没有更改*/");
        method.setName("update");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");

        method.addBodyLine("//按关键字更改");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "updateByPrimaryKeySelective" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method updateMethodLockWithCache(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*加一把分布式锁，然后按关键字更改" + introspectedTable.getRemarks() + "实例*/");
        method.addAnnotation("@LockWithCache");
        method.setName("updateLockWithCache");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");

        method.addBodyLine("//按关键字更改");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "updateByPrimaryKeySelective" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method updateMethodMockExecuteLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*起多线程按关键字更改" + introspectedTable.getRemarks() + "实例*/");
        method.addAnnotation("@MockExecuteLater");
        method.setName("updateMockExecuteLater");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");

        method.addBodyLine("//按关键字更改");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "updateByPrimaryKeySelective" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method updateByExampleMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*按查询条件更改" + introspectedTable.getRemarks() + "实例*/");
        method.setName("updateByExample");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.addParameter(new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example"));
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");

        method.addBodyLine("//按条件更改");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "updateByExample" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                "," +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example" +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method updateByExampleMethodLockWithCache(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*加一把分布式锁，按查询条件更改" + introspectedTable.getRemarks() + "实例*/");
        method.addAnnotation("@LockWithCache");
        method.setName("updateByExampleLockWithCache");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.addParameter(new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example"));
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");

        method.addBodyLine("//按条件更改");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "updateByExample" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                "," +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example" +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method updateByExampleMethodMockExecuteLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*起多线程按查询条件更改" + introspectedTable.getRemarks() + "实例*/");
        method.addAnnotation("@MockExecuteLater");
        method.setName("updateByExampleMockExecuteLater");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.addParameter(new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example"));
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//把所有字段设成非空");
        method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".setAllFieldsNotNull();");


        method.addBodyLine("//按条件更改");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "updateByExample" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                "," +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example" +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method updateByExampleSelectiveMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*按查询条件，部分更改" + introspectedTable.getRemarks() + "实例*/");
        method.setName("updateByExampleSelective");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.addParameter(new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example"));
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//按条件更改");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "updateByExampleSelective" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                "," +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example" +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method updateByExampleSelectiveMethodLockWithCache(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*加分布式锁，然后按查询条件，部分更改" + introspectedTable.getRemarks() + "实例*/");
        method.addAnnotation("@LockWithCache");
        method.setName("updateByExampleSelectiveLockWithCache");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.addParameter(new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example"));
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//按条件更改");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "updateByExampleSelective" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                "," +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example" +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method updateByExampleSelectiveMethodMockExecuteLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*起多线程，按查询条件，部分更改" + introspectedTable.getRemarks() + "实例*/");
        method.addAnnotation("@MockExecuteLater");
        method.setName("updateByExampleSelectiveMockExecuteLater");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName())));
        method.addParameter(new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example"));
        method.setVisibility(JavaVisibility.PUBLIC);

        method.addBodyLine("//按条件更改");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "updateByExampleSelective" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) +
                "," +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example" +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method deleteByExampleMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*按查询条件删除" + introspectedTable.getRemarks() + "*/");
        method.setName("deleteByExample");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example"));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addBodyLine("//删除");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "deleteByExample" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example" +
                ");");
        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method deleteByExampleMethodMockExecuteLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*起多线程按查询条件删除" + introspectedTable.getRemarks() + "*/");
        method.addAnnotation("@MockExecuteLater");
        method.setName("deleteByExampleMockExecuteLater");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example"));
        method.setVisibility(JavaVisibility.PUBLIC);
        method.addBodyLine("//删除");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "deleteByExample" +
                "(" +
                MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example" +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method deleteThenRemoveCacheFetchLaterAndCacheMockFetchLaterByPrimaryKeyMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*按关键字删除" + introspectedTable.getRemarks() + "实例*/");
        method.setName("deleteThenRemoveCacheFetchLaterAndCacheMockFetchLater");
        method.setReturnType(integer);
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);


        method.addBodyLine("//删除");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "deleteByPrimaryKey" +
                "(" +
                MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) +
                ");");

        method.addBodyLine("//设置参数");
        method.addBodyLine("Object[] argumentsValues = {" + MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) + "};");
        method.addBodyLine("//删除缓存");
        method.addBodyLine("cacheService.removeClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", "
                + "\"getWithCacheFetchLater\", argumentsValues" + ");");
        method.addBodyLine("//删除另一个缓存");
        method.addBodyLine("cacheService.removeClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", "
                + "\"getCacheMockFetchLater\", argumentsValues" + ");");
        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }


    private Method deleteByPrimaryKeyMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*按关键字删除" + introspectedTable.getRemarks() + "实例*/");
        method.setName("delete");
        method.setReturnType(integer);
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);


        method.addBodyLine("//删除");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "deleteByPrimaryKey" +
                "(" +
                MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method deleteByPrimaryKeyMethodLockWithCache(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*加一把分布式锁，然后按关键字删除" + introspectedTable.getRemarks() + "实例*/");
        method.addAnnotation("@LockWithCache");
        method.setName("deleteLockWithCache");
        method.setReturnType(integer);
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);


        method.addBodyLine("//删除");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "deleteByPrimaryKey" +
                "(" +
                MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method deleteByPrimaryKeyMethodMockExecuteLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*起多线程按关键字删除" + introspectedTable.getRemarks() + "实例*/");
        method.addAnnotation("@MockExecuteLater");
        method.setName("deleteMockExecuteLater");
        method.setReturnType(integer);
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);


        method.addBodyLine("//删除");
        method.addBodyLine("Integer result = " +
                getMapperShortWithDot() +
                "deleteByPrimaryKey" +
                "(" +
                MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) +
                ");");

        method.addBodyLine("//返回结果");
        method.addBodyLine("return result;");
        return method;
    }

    private Method deleteSetStatusByExampleMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*按查询条件把" + introspectedTable.getRemarks() + "实例的状态置成删除状态*/");
        method.setName("deleteSetStatusByExample");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example"));
        method.setVisibility(JavaVisibility.PUBLIC);
        if (MybatisUtilCommon.getTableHasStatus(introspectedTable)) {
            method.addBodyLine("//组装删除状态实例");
            method.addBodyLine(modelType.getShortName() + " " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = " + modelType.getShortName() + ".builder().status(STATUS_DELETE).build();");
            method.addBodyLine("//置入删除状态");
            method.addBodyLine("Integer result = " + getMapperShortWithDot() + "updateByPrimaryKeySelective(" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
            method.addBodyLine("//返回结果");
            method.addBodyLine("return result;");

        } else {
            method.addBodyLine("//当前表没有status字段");
            method.addBodyLine("return 0;");
        }
        return method;
    }

    private Method deleteSetStatusByExampleMethodMockExecuteLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*起多线程按查询条件把" + introspectedTable.getRemarks() + "实例的状态置成删除状态*/");
        method.addAnnotation("@MockExecuteLater");
        method.setName("deleteSetStatusByExampleMockExecuteLater");
        method.setReturnType(integer);
        method.addParameter(new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + "Example"));
        method.setVisibility(JavaVisibility.PUBLIC);
        if (MybatisUtilCommon.getTableHasStatus(introspectedTable)) {
            method.addBodyLine("//组装删除状态实例");
            method.addBodyLine(modelType.getShortName() + " " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = " + modelType.getShortName() + ".builder().status(STATUS_DELETE).build();");
            method.addBodyLine("//置入删除状态");
            method.addBodyLine("Integer result = " + getMapperShortWithDot() + "updateByPrimaryKeySelective(" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
            method.addBodyLine("//返回结果");
            method.addBodyLine("return result;");

        } else {
            method.addBodyLine("//当前表没有status字段");
            method.addBodyLine("return 0;");
        }
        return method;
    }

    private Method deleteSetStatusAndSetCacheFetchLaterAndCacheMockFetchLaterByPrimaryKeyMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*按关键字把" + introspectedTable.getRemarks() + "实例的状态置成删除状态，并删除缓存*/");
        method.setName("deleteSetStatusAndSetCacheFetchLaterAndCacheMockFetchLater");
        method.setReturnType(integer);
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);

        if (MybatisUtilCommon.getTableHasStatus(introspectedTable)) {
            method.addBodyLine("//组装删除状态实例");
            method.addBodyLine(modelType.getShortName() + " " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = " + modelType.getShortName() + ".builder().status(STATUS_DELETE).build();");
            List<IntrospectedColumn> introspectedColumns = introspectedTable.getPrimaryKeyColumns();
            Iterator<IntrospectedColumn> iterator = introspectedColumns.iterator();
            writePrimaryColumnSetterProperty(iterator, method);
            method.addBodyLine("//置入删除状态");
            method.addBodyLine("Integer result = " + getMapperShortWithDot() + "updateByPrimaryKeySelective(" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
            method.addBodyLine("//设置参数");
            method.addBodyLine("Object[] argumentsValues = {" + MybatisUtilCommon.getParameterValueForPrimaryKeyColumns(introspectedTable) + "};");
            method.addBodyLine("//删除缓存");
            method.addBodyLine("cacheService.removeClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                    "" + "\"getWithCacheFetchLater\", argumentsValues);");
            method.addBodyLine("//删除另一个缓存");
            method.addBodyLine("cacheService.removeClassMethodValue(\"" + servicePackage + "." + introspectedTable.getFullyQualifiedTable().getDomainObjectName() + "Service\", " +
                    "" + "\"getCacheMockFetchLater\", argumentsValues);");
            method.addBodyLine("return result;");
        } else {
            method.addBodyLine("return 0;");
        }
        return method;
    }

    private Method deleteSetStatusByPrimaryKeyMethod(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*按关键字把" + introspectedTable.getRemarks() + "实例的状态置成删除状态*/");
        method.setName("deleteSetStatus");
        method.setReturnType(integer);
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);
        if (MybatisUtilCommon.getTableHasStatus(introspectedTable)) {
            method.addBodyLine("//组装更改实例");
            method.addBodyLine(modelType.getShortName() + " " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = " + modelType.getShortName() + ".builder().status(STATUS_DELETE).build();");
            List<IntrospectedColumn> introspectedColumns = introspectedTable.getPrimaryKeyColumns();
            Iterator<IntrospectedColumn> iterator = introspectedColumns.iterator();

            method.addBodyLine("//置入id");
            writePrimaryColumnSetterProperty(iterator, method);
            method.addBodyLine("//置入删除状态");
            method.addBodyLine("Integer result = " + getMapperShortWithDot() + "updateByPrimaryKeySelective" + "(" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
            method.addBodyLine("//返回结果");
            method.addBodyLine("return result;");
        } else {
            method.addBodyLine("//当前表没有status字段");
            method.addBodyLine("return 0;");
        }
        return method;
    }

    private Method deleteSetStatusByPrimaryKeyMethodLockWithCache(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*加一把分布式锁，按关键字把" + introspectedTable.getRemarks() + "实例的状态置成删除状态*/");
        method.addAnnotation("@LockWithCache");
        method.setName("deleteSetStatusLockWithCache");
        method.setReturnType(integer);
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);

        judgeStatusToWriteUpdateStatus(introspectedTable, method);
        return method;
    }

    private Method deleteSetStatusByPrimaryKeyMethodMockExecuteLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*起多线程，按关键字把" + introspectedTable.getRemarks() + "实例的状态置成删除状态*/");
        method.addAnnotation("@MockExecuteLater");
        method.setName("deleteSetStatusMockExecuteLater");
        method.setReturnType(integer);
        MybatisUtilCommon.addParameterForPrimaryKeyColumnsInMethodSelectByPrimaryKey(method, introspectedTable);
        method.setVisibility(JavaVisibility.PUBLIC);

        judgeStatusToWriteUpdateStatus(introspectedTable, method);
        return method;
    }

    private void judgeStatusToWriteUpdateStatus(IntrospectedTable introspectedTable, Method method) {
        if (MybatisUtilCommon.getTableHasStatus(introspectedTable)) {
            method.addBodyLine("//组装删除状态实例");
            method.addBodyLine(modelType.getShortName() + " " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + " = " + modelType.getShortName() + ".builder().status(STATUS_DELETE).build();");
            List<IntrospectedColumn> introspectedColumns = introspectedTable.getPrimaryKeyColumns();
            Iterator<IntrospectedColumn> iterator = introspectedColumns.iterator();
            method.addBodyLine("//置入id");
            writePrimaryColumnSetterProperty(iterator, method);
            method.addBodyLine("//置入删除状态");
            method.addBodyLine("Integer result = " + getMapperShortWithDot() + "updateByPrimaryKeySelective" + "(" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ");");
            method.addBodyLine("//返回结果");
            method.addBodyLine("return result;");
        } else {
            method.addBodyLine("//当前表没有status字段");
            method.addBodyLine("return 0;");
        }
    }

    private void writePrimaryColumnSetterProperty(Iterator<IntrospectedColumn> iterator, Method method) {
        while (iterator.hasNext()) {
            IntrospectedColumn introspectedColumn = iterator.next();
            String columnName = introspectedColumn.getJavaProperty();
            if (introspectedColumn.isBLOBColumn()) {
            } else {
                method.addBodyLine(MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelType.getShortName()) + ".set" + MybatisUtilCommon.toUpperCaseAtFirstCharacter(columnName)
                        + "(" + columnName + ");"
                );
            }
        }
    }


    private Method list(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*自动缓存按查询条件获取" + introspectedTable.getRemarks() + "列表数据*/");
        method.setName("listWithCacheFetchLater");
        method.setReturnType(listT);
        method.addParameter(
                new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        if (introspectedTable.hasBLOBColumns()) {
            method.addBodyLine("//返回结果");
            method.addBodyLine(
                    "return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".selectByExampleWithBLOBs("
                            + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        } else {
            method.addBodyLine("//返回结果");
            method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".selectByExample("
                    + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        }
        method.addAnnotation("@CacheFetchLater");
        return method;
    }


    private Method listCacheMockFetchLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*纯缓存按查询条件获取" + introspectedTable.getRemarks() + "列表数据*/");
        method.setName("listCacheMockFetchLater");
        method.setReturnType(listT);
        method.addParameter(
                new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        if (introspectedTable.hasBLOBColumns()) {
            method.addBodyLine("//返回结果");
            method.addBodyLine(
                    "return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".selectByExampleWithBLOBs("
                            + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        } else {
            method.addBodyLine("//返回结果");
            method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".selectByExample("
                    + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        }
        method.addAnnotation("@CacheMockFetchLater");
        return method;
    }

    private Method listWithoutCache(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*无缓存按查询条件获取" + introspectedTable.getRemarks() + "列表数据*/");
        method.setName("listWithoutCache");
        method.setReturnType(listT);
        method.addParameter(
                new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        if (introspectedTable.hasBLOBColumns()) {
            method.addBodyLine("//返回结果");
            method.addBodyLine(
                    "return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".selectByExampleWithBLOBs("
                            + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        } else {
            method.addBodyLine("//返回结果");
            method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".selectByExample("
                    + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        }
        return method;
    }

    private Method countByExample(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*自动缓存按查询条件获取" + introspectedTable.getRemarks() + "数量数据*/");
        method.setName("countByExampleWithCacheFetchLater");
        method.setReturnType(longT);
        method.addParameter(
                new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        if (introspectedTable.hasBLOBColumns()) {
            method.addBodyLine("//返回结果");
            method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".countByExample("
                    + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        } else {
            method.addBodyLine("//返回结果");
            method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".countByExample("
                    + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        }
        method.addAnnotation("@CacheFetchLater");
        return method;
    }

    private Method countByExampleWithoutCache(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*无缓存按查询条件获取" + introspectedTable.getRemarks() + "数量数据*/");
        method.setName("countByExampleWithoutCache");
        method.setReturnType(longT);
        method.addParameter(
                new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        if (introspectedTable.hasBLOBColumns()) {
            method.addBodyLine("//返回结果");
            method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".countByExample("
                    + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        } else {
            method.addBodyLine("//返回结果");
            method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".countByExample("
                    + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        }
        return method;
    }

    private Method countByExampleCacheMockFetchLater(IntrospectedTable introspectedTable, String tableName) {
        Method method = new Method();
        method.addJavaDocLine("/*纯缓存按查询条件获取" + introspectedTable.getRemarks() + "数量数据*/");
        method.setName("countByExampleCacheMockFetchLater");
        method.setReturnType(longT);
        method.addParameter(
                new Parameter(modelExampleType, MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName())));
        method.setVisibility(JavaVisibility.PUBLIC);
        if (introspectedTable.hasBLOBColumns()) {
            method.addBodyLine("//返回结果");
            method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".countByExample("
                    + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        } else {
            method.addBodyLine("//返回结果");
            method.addBodyLine("return " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(mapperType.getShortName()) + ".countByExample("
                    + MybatisUtilCommon.toLowerCaseAtFirstCharacter(modelExampleType.getShortName()) + ");");
        }
        method.addAnnotation("@CacheMockFetchLater");
        return method;
    }

}
